home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / think / AmigaGnuChess.lha / chess / src.lha / src / util.c < prev    next >
C/C++ Source or Header  |  1992-09-01  |  9KB  |  393 lines

  1. /*
  2.  * util.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. extern char mvstr[4][6];
  25. int
  26. parse (FILE * fd, unsigned short int *mv, short int side, char *opening)
  27. {
  28.   register int c, i, r1, r2, c1, c2;
  29.   char s[128];
  30.   char *p;
  31.  
  32.   while ((c = getc (fd)) == ' ' || c == '\n') ;
  33.   i = 0;
  34.   s[0] = (char) c;
  35.   if (c == '!')
  36.     {
  37.       p = opening;
  38.       do
  39.     {
  40.       *p++ = c;
  41.       c = getc (fd);
  42.       if (c == '\n' || c == EOF)
  43.         {
  44.           *p = '\0';
  45.           return 0;
  46.         }
  47.       } while (true);
  48.     }
  49.   while (c != '?' && c != ' ' && c != '\t' && c != '\n' && c != EOF)
  50.     s[++i] = (char) (c = getc (fd));
  51.   s[++i] = '\0';
  52.   if (c == EOF)
  53.     return (-1);
  54.   if (s[0] == '!' || s[0] == ';' || i < 3)
  55.     {
  56.       while (c != '\n' && c != EOF)
  57.     c = getc (fd);
  58.       return (0);
  59.     }
  60.   if (s[4] == 'o')
  61.     *mv = ((side == black) ? LONGBLACKCASTLE : LONGWHITECASTLE);
  62.   else if (s[0] == 'o')
  63.     *mv = ((side == black) ? BLACKCASTLE : WHITECASTLE);
  64.   else
  65.     {
  66.       c1 = s[0] - 'a';
  67.       r1 = s[1] - '1';
  68.       c2 = s[2] - 'a';
  69.       r2 = s[3] - '1';
  70.       *mv = (locn (r1, c1) << 8) | locn (r2, c2);
  71.     }
  72.   if (c == '?')
  73.     {                /* Bad move, not for the program to play */
  74.       *mv |= 0x8000;        /* Flag it ! */
  75.       c = getc (fd);
  76.     }
  77.   return (1);
  78. }
  79.  
  80.  
  81. #if ttblsz
  82.  
  83. #define CB(i) (unsigned char) ((color[2 * (i)] ? 0x80 : 0)\
  84.            | (board[2 * (i)] << 4)\
  85.            | (color[2 * (i) + 1] ? 0x8 : 0)\
  86.            | (board[2 * (i) + 1]))
  87.  
  88. int
  89. ProbeTTable (short int side,
  90.          short int depth,
  91.          short int ply,
  92.          short int *alpha,
  93.          short int *beta,
  94.          short int *score)
  95.  
  96. /*
  97.  * Look for the current board position in the transposition table.
  98.  */
  99.  
  100. {
  101.   register struct hashentry *ptbl;
  102.   register short i;
  103.  
  104.   ptbl = &ttable[side][hashkey & (ttblsize - 1)];
  105.  
  106.   /* rehash max rehash times */
  107.   for (i = 1; (ptbl->depth) && (ptbl->hashbd != hashbd) && (i <= rehash); i++)
  108.     ptbl++;
  109.   if ((ptbl->depth) && (ptbl->hashbd == hashbd))
  110.     {
  111.       HashCnt++;
  112. #ifdef HASHTEST
  113.       for (i = 0; i < 32; i++)
  114.     {
  115.       if (ptbl->bd[i] != CB (i))
  116.         {
  117.           HashCol++;
  118.           ShowMessage (CP[199]);    /*ttable collision detected*/
  119.           break;
  120.         }
  121.     }
  122. #endif /* HASHTEST */
  123.  
  124.  
  125.       SwagHt = ptbl->mv;
  126.       if ((short) ptbl->depth >= depth)
  127.     {
  128.       PV = ptbl->mv;
  129.       if (ptbl->flags & truescore)
  130.         {
  131.           *score = ptbl->score;
  132.           /* adjust *score so moves to mate is from root */
  133.           if (*score > 9000)
  134.         *score -= ply;
  135.           else if (*score < -9000)
  136.         *score += ply;
  137.           *beta = -20000;
  138.         }
  139. #if 0                /* Never happens! see search */
  140.       else if (ptbl->flags & upperbound)
  141.         {
  142.           if (ptbl->score < *beta)
  143.         *beta = ptbl->score + 1;
  144.         }
  145. #endif
  146.       else if (ptbl->flags & lowerbound)
  147.         {
  148.           if (ptbl->score > *alpha)
  149.         *alpha = *score - 1;
  150.         }
  151.       return (true);
  152.     }
  153.     }
  154.   return (false);
  155. }
  156.  
  157. int
  158. PutInTTable (short int side,
  159.          short int score,
  160.          short int depth,
  161.          short int ply,
  162.          short int alpha,
  163.          short int beta,
  164.          unsigned short int mv)
  165.  
  166. /*
  167.  * Store the current board position in the transposition table.
  168.  */
  169.  
  170. {
  171.   register struct hashentry *ptbl;
  172.   register short i;
  173.  
  174.   ptbl = &ttable[side][hashkey & (ttblsize - 1)];
  175.  
  176.   /* rehash max rehash times */
  177.   for (i = 1; ptbl->depth && ptbl->hashbd != hashbd && i <= rehash; i++)
  178.     ptbl++;
  179.   if (i > rehash)
  180.     THashCol++;
  181.   if (depth >= ptbl->depth || ptbl->hashbd != hashbd)
  182.     {
  183.       HashAdd++;
  184.       ptbl->hashbd = hashbd;
  185.       ptbl->depth = (unsigned char) depth;
  186.       /* adjust score so moves to mate is from this ply */
  187.       if (score > 9000)
  188.     score += ply;
  189.       else if (score < -9000)
  190.     score -= ply;
  191.       ptbl->score = score;
  192.       ptbl->mv = mv;
  193. #ifdef DEBUG4
  194.       if (debuglevel & 32)
  195.     {
  196.       algbr (mv >> 8, mv & 0xff, 0);
  197.       printf ("-add-> d=%d s=%d p=%d a=%d b=%d %s\n", depth, score, ply, alpha, beta, mvstr);
  198.     }
  199. #endif
  200. /*#ifdef notdef
  201.       if (score < alpha)
  202.     ptbl->flags = upperbound;
  203.       else
  204. /*#endif /* 0 */
  205.       if (score > beta)
  206.     {
  207.       ptbl->flags = lowerbound;
  208.       score = beta + 1;
  209.     }
  210.       else
  211.     ptbl->flags = truescore;
  212.  
  213. #ifdef HASHTEST
  214.       for (i = 0; i < 32; i++)
  215.     {
  216.       ptbl->bd[i] = CB (i);
  217.     }
  218. #endif /* HASHTEST */
  219.       return true;
  220.     }
  221.   return false;
  222. }
  223.  
  224. void
  225. ZeroTTable (void)
  226. {
  227.   register int a;
  228.   for (a = 0; a < ttblsize + rehash; a++)
  229.     {
  230.       ttable[white][a].depth = 0;
  231.       ttable[black][a].depth = 0;
  232.     }
  233. #ifdef notdef
  234.   register struct hashentry *ptbl;
  235.   for (ptbl = &ttable[white][0]; ptbl < &ttable[white][ttblsize + rehash]; ptbl++)
  236.     ptbl->depth = 0;
  237.   for (ptbl = &ttable[black][0]; ptbl < &ttable[white][ttblsize + rehash]; ptbl++)
  238.     ptbl->depth = 0;
  239. #endif
  240. }
  241.  
  242. #ifdef HASHFILE
  243. int
  244. ProbeFTable (short int side,
  245.          short int depth,
  246.          short int ply,
  247.          short int *alpha,
  248.          short int *beta,
  249.          short int *score)
  250.  
  251. /*
  252.  * Look for the current board position in the persistent transposition table.
  253.  */
  254.  
  255. {
  256.   register short i, j;
  257.   register unsigned long hashix;
  258.   struct fileentry new, t;
  259.  
  260.   hashix = ((side == white) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) & filesz;
  261.  
  262.   for (i = 0; i < 32; i++)
  263.     new.bd[i] = CB (i);
  264.   new.flags = 0;
  265.   if (Mvboard[kingP[side]] == 0)
  266.     {
  267.       if (Mvboard[qrook[side]] == 0)
  268.     new.flags |= queencastle;
  269.       if (Mvboard[krook[side]] == 0)
  270.     new.flags |= kingcastle;
  271.     }
  272.   for (i = 0; i < frehash; i++)
  273.     {
  274.       fseek (hashfile,
  275.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  276.          SEEK_SET);
  277.       fread (&t, sizeof (struct fileentry), 1, hashfile);
  278.       if (!t.depth)
  279.     break;
  280.       for (j = 0; j < 32; j++)
  281.     if (t.bd[j] != new.bd[j])
  282.       break;
  283.       if (((short) t.depth >= depth) && (j >= 32)
  284.       && (new.flags == (t.flags & (kingcastle | queencastle))))
  285.     {
  286.       FHashCnt++;
  287.       PV = (t.f << 8) | t.t;
  288.       *score = (t.sh << 8) | t.sl;
  289.       /* adjust *score so moves to mate is from root */
  290.       if (*score > 9000)
  291.         *score -= ply;
  292.       else if (*score < -9000)
  293.         *score += ply;
  294.       if (t.flags & truescore)
  295.         {
  296.           *beta = -20000;
  297.         }
  298.       else if (t.flags & lowerbound)
  299.         {
  300.           if (*score > *alpha)
  301.         *alpha = *score - 1;
  302.         }
  303.       else if (t.flags & upperbound)
  304.         {
  305.           if (*score < *beta)
  306.         *beta = *score + 1;
  307.         }
  308.       return (true);
  309.     }
  310.     }
  311.   return (false);
  312. }
  313.  
  314. void
  315. PutInFTable (short int side,
  316.          short int score,
  317.          short int depth,
  318.          short int ply,
  319.          short int alpha,
  320.          short int beta,
  321.          unsigned short  int f,
  322.          unsigned short  int t)
  323.  
  324. /*
  325.  * Store the current board position in the persistent transposition table.
  326.  */
  327.  
  328. {
  329.   register unsigned short i;
  330.   register unsigned long hashix;
  331.   struct fileentry new, tmp;
  332.  
  333.   FHashAdd++;
  334.   hashix = ((side == white) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) & filesz;
  335.   for (i = 0; i < 32; i++)
  336.     new.bd[i] = CB (i);
  337.   new.f = (unsigned char) f;
  338.   new.t = (unsigned char) t;
  339.   if (score < alpha)
  340.     new.flags = upperbound;
  341.   else
  342.     new.flags = ((score > beta) ? lowerbound : truescore);
  343.   if (Mvboard[kingP[side]] == 0)
  344.     {
  345.       if (Mvboard[qrook[side]] == 0)
  346.     new.flags |= queencastle;
  347.       if (Mvboard[krook[side]] == 0)
  348.     new.flags |= kingcastle;
  349.     }
  350.   new.depth = (unsigned char) depth;
  351.   /* adjust *score so moves to mate is from root */
  352.   if (score > 9000)
  353.     score += ply;
  354.   else if (score < -9000)
  355.     score -= ply;
  356.  
  357.  
  358.   new.sh = (unsigned char) (score >> 8);
  359.   new.sl = (unsigned char) (score & 0xFF);
  360.  
  361.   for (i = 0; i < frehash; i++)
  362.     {
  363.       fseek (hashfile,
  364.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  365.          SEEK_SET);
  366.       fread (&tmp, sizeof (struct fileentry), 1, hashfile);
  367.       if ((short) tmp.depth <= depth)
  368.     {
  369.       fseek (hashfile,
  370.          sizeof (struct fileentry) * ((hashix + 2 * i) & (filesz)),
  371.          SEEK_SET);
  372.       fwrite (&new, sizeof (struct fileentry), 1, hashfile);
  373.       break;
  374.     }
  375.     }
  376. }
  377.  
  378. #endif /* HASHFILE */
  379. #endif /* ttblsz */
  380.  
  381. void
  382. ZeroRPT (void)
  383. {
  384. #ifdef NOMEMSET
  385.   register int side, i;
  386.   for (side = white; side <= black; side++)
  387.     for (i = 0; i < 256;)
  388.       rpthash[side][i++] = 0;
  389. #else
  390.    memset ((char *) rpthash, 0, sizeof (rpthash));
  391. #endif
  392. }
  393.